package com.example.controller;

import com.alibaba.fastjson.JSONObject;
import com.example.service.UserService;
import com.example.shiro.SysUserEntity;
import com.example.shiro.util.ShiroUtils;
import com.example.utils.*;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;


/**
 * @description:
 * @author: xxx
 * @create: 2022/4/12 15:21
 */
@RestController
@RequestMapping("/oauth")
public class OauthController {
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private UserService userService;
    @GetMapping("/login")
    public String hello(){
        JSONObject jsonObject = new JSONObject();
        System.out.println(userService.getList(jsonObject));
        return "hello provider";
    }
    /**
     * 未登录
     *
     * @Author Sans
     * @CreateTime 2019/6/20 9:22
     */
    @RequestMapping("/unauth")
    public Result unauth() {
        return ResultUtil.error(403,"未登录");
    }
    @RequestMapping("/logout")
    public Result logout() {
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession();
        System.out.println("退出："+session.toString());
        if (subject.isAuthenticated()) {
            subject.logout();
        }
        Map<String, Object> map = new HashMap<>();
        map.put("msg", "退出成功");
        return ResultUtil.success(map);
    }
    @RequestMapping("/login")
    public Result login(@RequestBody Map<String, Object> map){

        Map<String, String> mapUserName = new HashMap<>();
        String name = map.get("name").toString();
        String password = map.get("password").toString();

            mapUserName.put("name",name);
            SysUserEntity userEntity = userService.getUserByNameGld(name);
            //如果mapUser不为空，已经注册
            if(userEntity!=null && userEntity.getType().equals("m")) {
                String verifyCode = map.get("verifyCode").toString();
                //3.获取生成的验证码信息
                String uuid = map.get("uuid").toString();
                if (redisUtil.get("verifyCode:"+uuid) != null){
                    String key = "verifyCode:"+uuid;
                    String verifyCode_redis = redisUtil.get(key).toString().toLowerCase();
                    //由于redis存储了验证码信息,所以当跳转后在浏览器点返回时候,不改变验证码又可以登录了.所以要在获取后立即删除
                    redisUtil.delete(key);
                    if (verifyCode != null && verifyCode.toLowerCase().equals(verifyCode_redis)){
                        Map<String, Object> mapNew = new HashMap<>();
                        try {
                            //验证身份和登陆
                            Subject subject = SecurityUtils.getSubject();
                            UsernamePasswordToken token = new UsernamePasswordToken(name, password);
                            //进行登录操作
                            subject.login(token);
                            //保存登陆信息到session
                            Session session = ShiroUtils.getSession();
                            Map<String, Object>  userInfo =  userService.selectUserByUserName(name);
                            userInfo.put("token", ShiroUtils.getSession().getId().toString());
                            session.setAttribute("userInfo",userInfo);
                            mapNew.put("userInfo",userInfo);
                            return ResultUtil.success(mapNew);
                        } catch (IncorrectCredentialsException e) {
                            return ResultUtil.error(500,"用户不存在或者密码错误");
                        } catch (LockedAccountException e) {
                            return ResultUtil.error(500,"登录失败，该用户已被冻结");
                        } catch (AuthenticationException e) {
                            return ResultUtil.error(500,"该用户不存在");
                        } catch (Exception e) {
                            e.printStackTrace();
                            return ResultUtil.error(500,"未知异常");
                        }
                    }else{
                        return ResultUtil.error(500,"验证码错误");
                    }
                }else{
                    return ResultUtil.error(500,"验证码错误");
                }
            }else {//否则用户不存在
                return ResultUtil.error(500,"用户不存在");
            }


    }
    /**
     * 生成6位随机数验证码
     * @return
     */
    public static String vcode(){
        String vcode = "";
        for (int i = 0; i < 6; i++) {
            vcode = vcode + (int)(Math.random() * 9);
        }
        return vcode;
    }

    /* 获取验证码图片*/

    @RequestMapping("/getVerifyCode")
    public Result getVerificationCode(HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            int width=200;
            int height=69;
            //生成对应宽高的初始图片
            BufferedImage verifyImg=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
            //单独的一个类方法，出于代码复用考虑，进行了封装。
            String randomText = VerifyCode.drawRandomText(width,height,verifyImg);
            //功能是生成验证码字符并加上噪点，干扰线，返回值为验证码字符
            response.setContentType("image/png");//必须设置响应内容类型为图片，否则前台不识别
            //将图片转换陈字符串给前端
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            ImageIO.write(verifyImg, "png", stream);
            String base64 = Base64.encode(stream.toByteArray());
            stream.flush();
            stream.close();
            //封装数据
            String uuid = IDTool.getUUID32();
            result.put("image", "data:image/png;base64,"+base64);
            result.put("uuid", uuid);
            redisUtil.set("verifyCode:"+uuid,randomText.toLowerCase(),5L, TimeUnit.MINUTES);


        } catch (IOException e) {
            e.printStackTrace();

        }
        return ResultUtil.success(result);
    }
}
